<template>
  <div class="liteflow-sidebar">
    <section
      v-for="group in groups"
      :key="group.key"
      class="liteflow-sidebar__section"
    >
      <header class="liteflow-sidebar__header" @click="toggle(group.key)">
        <span>{{ group.name }}</span>
        <span class="liteflow-sidebar__header-icon">{{ isOpen(group.key) ? '−' : '+' }}</span>
      </header>
      <div v-if="isOpen(group.key)" class="liteflow-sidebar__content">
        <div
          v-for="(cell, index) in group.cellTypes"
          :key="index"
          class="liteflow-sidebar__item"
          @mousedown.prevent="startDrag($event, cell)"
        >
          <div class="liteflow-sidebar__icon-wrapper">
            <img :src="cell.icon" class="liteflow-sidebar__icon" :alt="cell.label" />
          </div>
          <p class="liteflow-sidebar__label">{{ cell.label }}</p>
        </div>
      </div>
    </section>
  </div>
</template>

<script>
import { Node, Edge } from '@antv/x6';
import { Dnd } from '@antv/x6-plugin-dnd';
import { PALETTE_GROUPS } from '../core/palette/groups.js';
import { findViewsFromPoint } from '../core/common/events.js';
import ELBuilder from '../core/model/builder.js';
import { history } from '../core/history/index.js';
import { getModel } from '../core/state/model.js';

export default {
  name: 'SideBar',
  props: {
    flowGraph: {
      required: true,
    },
  },
  data() {
    return {
      dnd: null,
      groups: PALETTE_GROUPS,
      openKeys: new Set(PALETTE_GROUPS.map((item) => item.key)),
      lastEdge: null,  // 跟踪最后 hover 的边
      isDragging: false,  // 是否正在拖动
    };
  },
  created() {
    this.dnd = new Dnd({
      target: this.flowGraph,
      scaled: true,
      validateNode: this.validateNode,
    });
    
    // 监听边的 hover 事件
    this.flowGraph.on('edge:mouseover', ({ edge }) => {
      this.lastEdge = edge;
      // 拖动时强制显示 + 号
      if (this.isDragging) {
        this.showEdgeButton(edge);
      }
    });
    this.flowGraph.on('edge:mouseleave', () => {
      const prevEdge = this.lastEdge;
      this.lastEdge = null;
      // 拖动时隐藏 + 号
      if (this.isDragging && prevEdge) {
        this.hideEdgeButton(prevEdge);
      }
    });
  },
  beforeDestroy() {
    if (this.dnd) {
      this.dnd.dispose();
    }
    // 清理事件监听
    if (this.flowGraph) {
      this.flowGraph.off('edge:mouseover');
      this.flowGraph.off('edge:mouseleave');
    }
  },
  methods: {
    toggle(key) {
      if (this.openKeys.has(key)) {
        this.openKeys.delete(key);
      } else {
        this.openKeys.add(key);
      }
      this.openKeys = new Set(this.openKeys);
    },
    isOpen(key) {
      return this.openKeys.has(key);
    },
    startDrag(evt, cell) {
      if (!this.dnd) return;
      // 创建拖拽节点，将 cell 信息存入 data.node
      const node = Node.create({
        shape: cell.shape,
        data: {
          node: cell,  // React 版本也是存为 node
        },
      });
      this.isDragging = true;
      this.dnd.start(node, evt);
      // 监听拖动过程
      document.addEventListener('mousemove', this.onDragging);
      document.addEventListener('mouseup', this.onDragEnd, { once: true });
    },
    onDragging(evt) {
      // 检测鼠标位置下方是否有边
      const point = this.flowGraph.clientToLocal(evt.clientX, evt.clientY);
      const views = this.flowGraph.findViewsInArea({
        x: point.x - 10,
        y: point.y - 10,
        width: 20,
        height: 20,
      });
      
      const edgeView = views.find(view => view.isEdgeView());
      
      if (edgeView) {
        const edge = edgeView.cell;
        if (edge !== this.lastEdge) {
          // 隐藏之前的 +
          if (this.lastEdge) {
            this.hideEdgeButton(this.lastEdge);
          }
          // 显示当前的 +
          this.showEdgeButton(edge);
          this.lastEdge = edge;
        }
      } else {
        // 没有边，隐藏 +
        if (this.lastEdge) {
          this.hideEdgeButton(this.lastEdge);
          this.lastEdge = null;
        }
      }
    },
    onDragEnd() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.onDragging);
      // 隐藏所有边的 + 号
      this.flowGraph.getEdges().forEach(edge => {
        this.hideEdgeButton(edge);
      });
      this.lastEdge = null;
    },
    showEdgeButton(edge) {
      const view = this.flowGraph.findViewByCell(edge);
      if (view && view.container) {
        view.container.classList.add('edge-dragging-hover');
      }
    },
    hideEdgeButton(edge) {
      const view = this.flowGraph.findViewByCell(edge);
      if (view && view.container) {
        view.container.classList.remove('edge-dragging-hover');
      }
    },
    validateNode(droppingNode) {
      const { node } = droppingNode.getData();
      
      if (!node) return false;
      
      // 检查是否 hover 到边上（+ 号默认就在边上，hover 时显示）
      if (this.lastEdge) {
        const targetNode = this.lastEdge.getTargetNode();
        const sourceNode = this.lastEdge.getSourceNode();
        
        if (targetNode && sourceNode) {
          const targetData = targetNode.getData();
          const sourceData = sourceNode.getData();
          const targetModel = targetData?.model;
          const sourceModel = sourceData?.model;
          
          if (targetModel && sourceModel) {
            // 创建新节点
            const newNode = ELBuilder.createELNode(node.type, targetModel);
            
            // 检查是否有多个入边
            const inComingEdges = this.flowGraph.getIncomingEdges(targetNode) || [];
            
            if (inComingEdges.length > 1 || (sourceModel && targetModel.isParentOf(sourceModel))) {
              // 后插
              sourceModel.append(newNode);
            } else {
              // 前插
              targetModel.prepend(newNode);
            }
            
            history.push();
            return false;
          }
        }
      }
      
      // 如果没有 + 号，检查是否是第一次添加（没有连接线）
      const hasEdges = this.flowGraph.getEdges().length > 0;
      
      if (!hasEdges) {
        // 没有连接线，可以添加到根节点
        const elNode = ELBuilder.createELNode(node.type);
        const rootModel = getModel();
        if (rootModel) {
          rootModel.append(elNode);
          history.push();
        }
      }
      // 如果有连接线但没有 + 号，不添加节点
      
      // 总是返回 false，防止 dnd 插件继续处理
      return false;
    },
  },
};
</script>

<style lang="less" scoped>
.liteflow-sidebar {
  padding: 12px 16px;
}

.liteflow-sidebar__section + .liteflow-sidebar__section {
  margin-top: 12px;
}

.liteflow-sidebar__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;
  font-weight: 600;
  color: #1f2d3d;
  cursor: pointer;
  user-select: none;
}

.liteflow-sidebar__header-icon {
  font-size: 18px;
  line-height: 1;
}

.liteflow-sidebar__content {
  margin-top: 8px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.liteflow-sidebar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px;
  border-radius: 8px;
  cursor: grab;
  transition: all 0.2s ease;

  &:hover {
    background: #e8f4ff;
  }
}

.liteflow-sidebar__icon-wrapper {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 4px 12px rgba(30, 64, 175, 0.12);
}

.liteflow-sidebar__icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.liteflow-sidebar__label {
  margin: 0;
  font-size: 12px;
  color: #3c4a69;
  text-align: center;
}
</style>

